﻿using Datos.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Entidad;
using Dapper;
using DapperExtensions;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq.Expressions;
using Microsoft.Practices.EnterpriseLibrary.Data;
using System.Configuration;

namespace Datos.Repositories
{
    public class ClienteRepository:IClienteRepository
    {
        private readonly Microsoft.Practices.EnterpriseLibrary.Data.Database _db;

        public ClienteRepository()
        {
            _db = DatabaseFactory.CreateDatabase("RealConnection");
        }

        public IList<Cliente> FindAll()
        {
            
            using (IDbConnection conn = _db.CreateConnection())
            {
                const string query = @"SELECT * FROM Cliente C
                                        JOIN Ciudad I ON I.Id = C.IdCiudad
                                        JOIN Provincia P ON P.Id = C.IdProvincia
                                        JOIN TipoIva T ON T.Id = C.IdTipoIva";

                var datos = conn.Query<Cliente, Ciudad, Provincia, TipoIva, Cliente>
                    (query, (cliente, ciudad, provincia, tipoiva) =>
                    {
                        cliente.Ciudad = ciudad;
                        cliente.Provincia = provincia;
                        cliente.TipoIva = tipoiva;

                        return cliente;
                    });

                return datos.ToList();
            }
        }

        public IQueryable<Cliente> Find(Expression<Func<Cliente, bool>> predicate)
        {
            throw new NotImplementedException();
        }

        public Cliente FindById(int id)
        {
            using (IDbConnection conn = _db.CreateConnection())
            {
                return conn.Get<Cliente>(id);
            }
        }

        public IList<Cliente> FindByNombre(string nombre)
        {
            using (IDbConnection conn = _db.CreateConnection())
            {
                string query = @"SELECT * FROM Cliente C
                                JOIN Ciudad I ON I.Id = C.IdCiudad
                                JOIN Provincia P ON P.Id = C.IdProvincia
                                JOIN TipoIva T ON T.Id = C.IdTipoIva
                                WHERE C.Nombre LIKE '" + nombre + "' OR C.Apellido LIKE '" + nombre + "'";

                var datos = conn.Query<Cliente, Ciudad, Provincia, TipoIva, Cliente>
                    (query, (cliente, ciudad, provincia, tipoiva) =>
                    {
                        cliente.Ciudad = ciudad;
                        cliente.Provincia = provincia;
                        cliente.TipoIva = tipoiva;

                        return cliente;
                    });

                return datos.ToList();
            }
        }

        public int Add(Cliente newEntity)
        {
            using (IDbConnection conn = _db.CreateConnection())
            {
                const string query = @"INSERT INTO Cliente(Nombre, Apellido,
                                        Documento, Calle, Numeracion, Piso, 
                                        Departamento, Barrio, TelefonoFijo, 
                                        TelefonoCelular, Email, IdCiudad, 
                                        IdProvincia, IdTipoIva)
                                       VALUES (
                                        @nombre, @apellido, 
                                        @documento, @calle, @numeracion, @piso, 
                                        @departamento, @barrio, @telefonoFijo, 
                                        @telefonoCelular, @email, @idCiudad,
                                        @idProvincia, @idTipoIva)";

                return conn.Execute(query, new
                {
                    newEntity.Nombre,
                    newEntity.Apellido,
                    newEntity.Documento,
                    newEntity.Calle,
                    newEntity.Numeracion,
                    newEntity.Piso,
                    newEntity.Departamento,
                    newEntity.Barrio,
                    newEntity.TelefonoFijo,
                    newEntity.TelefonoCelular,
                    newEntity.Email,
                    idCiudad = newEntity.Ciudad.Id,
                    idProvincia = newEntity.Provincia.Id,
                    idTipoIva = newEntity.TipoIva.Id,
                });

            }
        }

        public bool Remove(int id)
        {
            using (IDbConnection conn = _db.CreateConnection())
            {
                bool deleted = conn.Delete(conn.Get<Cliente>(id));
                return deleted;
            }
        }

        public int Modify(Cliente cli)
        {
            using (IDbConnection conn = _db.CreateConnection())
            {
                if (conn.Update(cli))
                {
                    return 1;
                }
                return 0;
            }
        }
    }
}
